package com.ews.onlineexchange.service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.enterprise.context.ConversationScoped;
import javax.enterprise.event.Event;
import javax.inject.Inject;
import javax.inject.Named;

import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;

import com.ews.onlineexchange.controller.activitii.BpmHome;
import com.ews.onlineexchange.model.BestTradeEvaluation;
import com.ews.onlineexchange.model.Bulletin;
import com.ews.onlineexchange.model.Trade;
import com.ews.onlineexchange.service.qualifier.MessagePushWsEvent;
import com.ews.onlineexchange.util.AttachmentUtils;

@Named
@ConversationScoped
public class TradeHome extends EntityHome<Trade, String> {

	/**
	 * 
	 */
	private static final long	serialVersionUID	= 1L;

	@Inject
	@MessagePushWsEvent
	Event<String>				messagePushWsEvent;

	@Inject
	MessgaePushService			messgaePushService;
	
	@Inject
	NotificationService			notificationService;
	
	@Inject
	SmsService					smsService;
	
	@Inject
	AttachmentUtils 			attachmentUtils;
	
	@Inject
	BpmHome						bpmHome;

	@Inject
	RuntimeService				runtimeService;

	@Inject
	TaskService					taskService;

	@Override
	public String saveAndFlush() {
		getInstance().setApply( true );
		getInstance().setApplyTime( new Date() );
		getInstance().setHasVerify( true );
		getInstance().setVerifyTime( new Date() );
		return super.saveAndFlush();
	}
	
	private Map<String, BestTradeEvaluation> bestTradeEvaluationMap;
	public Map<String, BestTradeEvaluation> getBestTradeEvaluationMap() {
		return bestTradeEvaluationMap;
	}

	public void setBestTradeEvaluationMap( Map<String, BestTradeEvaluation> bestTradeEvaluationMap ) {
		this.bestTradeEvaluationMap = bestTradeEvaluationMap;
	}
	
	@Inject
	BestTradeEvaluationService bestTradeEvaluationService;
	public String assessBestChooseTrade() {
		Set<String> keySet = bestTradeEvaluationMap.keySet();
		for ( String string : keySet ) {
			BestTradeEvaluation ev = bestTradeEvaluationMap.get( string );
			//避免重复保存
			BigDecimal count = bestTradeEvaluationService.getBestTradeEvaluationByTradeAndReq(ev.getTrade().getId(), ev.getRequirementDefination().getId());
			if(count.compareTo(new BigDecimal(0)) >0 && StringUtils.isBlank(ev.getId())) {
				continue;
			}
			getEntityManagerDao().updateObject( ev );
		}		
		saveAndFlush();
		return "BestChooseAudit.xhtml?bulletinId=".concat( getInstance().getBulletin().getId() ).concat( "&taskId=".concat( bpmHome.getTaskId() ) ).concat( "&faces-redirect=true" );
	}

	public String cancelApply() {
		Bulletin bulletin = getInstance().getBulletin();
//		bulletin.setHasAppliedCount( bulletin.getAppliedCount() - 1 );
		getEntityManager().merge( bulletin );
		getInstance().setApply( false );
		getInstance().setHasVerify( false );
		getInstance().setVerifyTime( null );
		getInstance().setApplyTime( null );
		getInstance().setRequirements( null );
		String message = messgaePushService.addCancelAppliedMessageToSupplier( getInstance() );
		messagePushWsEvent.fire( message );
		return super.saveAndFlush();
	}

	/**采购方发起取消报名的申请
	 * @return
	 */
	public String cancelApplyByBuyer() {
		getInstance().setCancelAudit("1");
		String result = super.saveAndFlush();
		if ( result.equals( RESULT_SAVED ) ) {
			startApplyCancelProcess();
			return "ApplyAudit.xhtml?faces-redirect=true&amp;includeViewParams=true";
		} else
			return null;
	}
	
	
	private void startApplyCancelProcess() {
		Task task = null;
		if ( StringUtils.isBlank( bpmHome.getTaskId() ) ) {
			HashMap<String, Object> variables = new HashMap<String, Object>();
			variables.put( "initiator", userService.getLoginedUser().getUsername() );
			variables.put( "tradeId", getInstance().getId() );
			variables.put( "bulletinId", getInstance().getBulletin().getId() );
			variables.put( "projectName", getInstance().getBulletin().getProjectName() );
			variables.put( "supplierName", getInstance().getSupplier().getCnname() );
			variables.put( "supplierRegion", getInstance().getBulletin().getBuyer().getRegion() );
//			Map beanMap = new BeanMap( getInstance() );			
//			variables.putAll( beanMap );
			
			ProcessInstance process = runtimeService.startProcessInstanceByKey( "applyCancelAudit", getInstance().getId(), variables );			
			
			List<Task> list = taskService.createTaskQuery().processInstanceId( process.getId() ).list();
			task = list.get( 0 );			
		} else {
			task = taskService.createTaskQuery().taskId( bpmHome.getTaskId() ).singleResult();
		}
		
		taskService.claim( task.getId(), userService.getLoginedUser().getUsername() );
		taskService.complete( task.getId() );
	}
	
	public String adminReject() {
		String taskId = bpmHome.getTaskId(); 
		taskService.claim( taskId, userService.getLoginedUser().getUsername() );
		taskService.setVariable( taskId, "auditFlag", false );
		taskService.setVariable( taskId, "to", "buyer" );
		taskService.setVariable( taskId, "adminRejectReason", getInstance().getAdminRejectReason() );
		taskService.setVariableLocal( taskId, "auditFlag", false );
		taskService.setVariableLocal( taskId, "adminRejectReason", getInstance().getAdminRejectReason() );
		taskService.complete( taskId );		
		this.saveAndFlush();
		return "CancelApplyTaskList.xhtml?processKey=applyCancelAudit&faces-redirect=true&amp;includeViewParams=true";
//		getInstance().setApply( false );
//		getInstance().setHasVerify( false );
//		getInstance().setVerifyTime( null );
//		getInstance().setApplyTime( null );
////		getInstance().setRequirements( null );
//		String result = super.saveAndFlush();
//		if ( result.equals( RESULT_SAVED ) ) {
//			notificationService.addCancelAppliedByBuyerMessageToSupplier( getInstance() );
//			smsService.cancelAppliedByBuyer( getInstance() );
//			return "ApplyAudit.xhtml?faces-redirect=true&amp;includeViewParams=true";
//		} else
//			return null;
	}
	public String adminAudit() {
		String taskId = bpmHome.getTaskId(); 
		taskService.claim( taskId, userService.getLoginedUser().getUsername() );
		taskService.setVariable( taskId, "auditFlag", true );
		taskService.setVariable( taskId, "to", "buyer" );
		taskService.setVariable( taskId, "adminRejectReason", getInstance().getAdminRejectReason() );
		taskService.setVariableLocal( taskId, "auditFlag", true );
		taskService.setVariableLocal( taskId, "adminRejectReason", getInstance().getAdminRejectReason() );
		taskService.complete( taskId );	
		if(getInstance().getBulletin().getChooseTime().after(new Date())) {//当未选取之前 才会设置报名的标志位 否则不设置，直接结束这个流程
			getInstance().setApply( false );
			getInstance().setHasVerify( false );
			getInstance().setVerifyTime( null );
			getInstance().setApplyTime( null );
		}
		
		String result = super.saveAndFlush();
		if ( result.equals( RESULT_SAVED ) ) {
			notificationService.addCancelAppliedByBuyerMessageToSupplier( getInstance() );
			smsService.cancelAppliedByBuyer( getInstance() );
			return "CancelApplyTaskList.xhtml?processKey=applyCancelAudit&amp;faces-redirect=true&amp;includeViewParams=true";
		} else
			return null;
	}
	
	public String buyerRestart() {
		String result = this.saveAndFlush();
		if ( result != null ) {
			startApplyCancelProcess();
			return "BuyerCancelApplyTaskList.xhtml?processKey=applyCancelAudit&amp;faces-redirect=true&amp;includeViewParams=true";
		}
		
		return null;
	}
}
